In [7]:
import numpy as np
import scipy
import matplotlib.pyplot as plt
from scipy.io import wavfile
%matplotlib inline
In [13]:
!pip install mir_eval
Collecting mir_eval
  Downloading https://files.pythonhosted.org/packages/bb/dc/a22af4ad364742e65922fb8bf0de14d63b6ec3e08ae7ce20fad522b999b7/mir_eval-0.5.tar.gz (86kB)
    100% |████████████████████████████████| 92kB 3.8MB/s ta 0:00:011
Requirement already satisfied: numpy>=1.7.0 in /anaconda3/lib/python3.6/site-packages (from mir_eval)
Requirement already satisfied: scipy>=1.0.0 in /anaconda3/lib/python3.6/site-packages (from mir_eval)
Requirement already satisfied: future in /anaconda3/lib/python3.6/site-packages (from mir_eval)
Requirement already satisfied: six in /anaconda3/lib/python3.6/site-packages (from mir_eval)
Building wheels for collected packages: mir-eval
  Running setup.py bdist_wheel for mir-eval ... done
  Stored in directory: /Users/adityagudal/Library/Caches/pip/wheels/69/d2/fe/892fae0039b51e3774a92daac135e45268ff5f52f28b99f4e4
Successfully built mir-eval
Installing collected packages: mir-eval
Successfully installed mir-eval-0.5
You are using pip version 9.0.1, however version 19.0.2 is available.
You should consider upgrading via the 'pip install --upgrade pip' command.
In [8]:
!pip install librosa
Collecting librosa
  Downloading https://files.pythonhosted.org/packages/09/b4/5b411f19de48f8fc1a0ff615555aa9124952e4156e94d4803377e50cfa4c/librosa-0.6.2.tar.gz (1.6MB)
    100% |████████████████████████████████| 1.6MB 126kB/s ta 0:00:011
Collecting audioread>=2.0.0 (from librosa)
  Downloading https://files.pythonhosted.org/packages/f0/41/8cd160c6b2046b997d571a744a7f398f39e954a62dd747b2aae1ad7f07d4/audioread-2.1.6.tar.gz
Requirement already satisfied: numpy>=1.8.0 in /anaconda3/lib/python3.6/site-packages (from librosa)
Requirement already satisfied: scipy>=0.14.0 in /anaconda3/lib/python3.6/site-packages (from librosa)
Requirement already satisfied: scikit-learn!=0.19.0,>=0.14.0 in /anaconda3/lib/python3.6/site-packages (from librosa)
Collecting joblib>=0.12 (from librosa)
  Downloading https://files.pythonhosted.org/packages/49/d9/4ea194a4c1d0148f9446054b9135f47218c23ccc6f649aeb09fab4c0925c/joblib-0.13.1-py2.py3-none-any.whl (278kB)
    100% |████████████████████████████████| 286kB 2.7MB/s ta 0:00:01
Requirement already satisfied: decorator>=3.0.0 in /anaconda3/lib/python3.6/site-packages (from librosa)
Requirement already satisfied: six>=1.3 in /anaconda3/lib/python3.6/site-packages (from librosa)
Collecting resampy>=0.2.0 (from librosa)
  Downloading https://files.pythonhosted.org/packages/14/b6/66a06d85474190b50aee1a6c09cdc95bb405ac47338b27e9b21409da1760/resampy-0.2.1.tar.gz (322kB)
    100% |████████████████████████████████| 327kB 2.2MB/s ta 0:00:01
Collecting numba>=0.38.0 (from librosa)
  Downloading https://files.pythonhosted.org/packages/6a/96/3bf2f9723cb9455de5ad48b50b23674829c8136630b487716af9e08963d3/numba-0.42.1-cp36-cp36m-macosx_10_9_x86_64.whl (1.6MB)
    100% |████████████████████████████████| 1.6MB 462kB/s ta 0:00:01
Collecting llvmlite>=0.27.0dev0 (from numba>=0.38.0->librosa)
  Downloading https://files.pythonhosted.org/packages/dd/ad/fec27334d072762ca0af8350f5bd2d44aa7c5934f310f2c8368e2b6a7114/llvmlite-0.27.1-cp36-cp36m-macosx_10_9_x86_64.whl (13.2MB)
    100% |████████████████████████████████| 13.2MB 79kB/s eta 0:00:01
Building wheels for collected packages: librosa, audioread, resampy
  Running setup.py bdist_wheel for librosa ... done
  Stored in directory: /Users/adityagudal/Library/Caches/pip/wheels/18/b8/10/f0f8f6ac60668a5cd75596cf14c25bb6b3ea1ecd815f058b7e
  Running setup.py bdist_wheel for audioread ... done
  Stored in directory: /Users/adityagudal/Library/Caches/pip/wheels/53/02/90/7b5c4081b7470c550ab605f600bad237dde12a6b8999b11f50
  Running setup.py bdist_wheel for resampy ... done
  Stored in directory: /Users/adityagudal/Library/Caches/pip/wheels/ff/4f/ed/2e6c676c23efe5394bb40ade50662e90eb46e29b48324c5f9b
Successfully built librosa audioread resampy
Installing collected packages: audioread, joblib, llvmlite, numba, resampy, librosa
  Found existing installation: llvmlite 0.21.0
    Uninstalling llvmlite-0.21.0:
      Successfully uninstalled llvmlite-0.21.0
  Found existing installation: numba 0.36.2
    Uninstalling numba-0.36.2:
      Successfully uninstalled numba-0.36.2
Successfully installed audioread-2.1.6 joblib-0.13.1 librosa-0.6.2 llvmlite-0.27.1 numba-0.42.1 resampy-0.2.1
You are using pip version 9.0.1, however version 19.0.2 is available.
You should consider upgrading via the 'pip install --upgrade pip' command.
In [8]:
import seaborn as sns
sns.set(style='ticks')
In [9]:
from IPython.display import Audio
import mir_eval
import librosa
import librosa.display
In [19]:
y,sampling_rate=librosa.load(librosa.util.example_audio_file())
print(y.shape,sampling_rate)
(1355168,) 22050
In [20]:
Audio(data=y,rate=sampling_rate)
Out[20]:
In [32]:
librosa.display.waveplot(y,sampling_rate);
In [31]:
D=librosa.stft(y)
---------------------------------------------------------------------------
ImportError                               Traceback (most recent call last)
<ipython-input-31-d1fad772867d> in <module>()
----> 1 from librosa import log_power

ImportError: cannot import name 'log_power'
In [38]:
librosa.display.specshow(np.log(D**2),x_axis='time',y_axis='log')
plt.colorbar();
/anaconda3/lib/python3.6/site-packages/librosa/display.py:665: UserWarning: Trying to display complex-valued input. Showing magnitude instead.
  warnings.warn('Trying to display complex-valued input. '
In [33]:
plt.plot(D);
/anaconda3/lib/python3.6/site-packages/numpy/core/numeric.py:492: ComplexWarning: Casting complex values to real discards the imaginary part
  return array(a, dtype, copy=False, order=order)
In [39]:
C=librosa.cqt(y,sampling_rate)
In [42]:
log_power=librosa.power_to_db(D**2,ref=np.max)
log_amp=librosa.power_to_db(C**2)
librosa.display.specshow(log_amp,x_axis='time',y_axis='cqt_hz')
plt.colorbar();
/anaconda3/lib/python3.6/site-packages/librosa/core/spectrum.py:865: UserWarning: power_to_db was called on complex input so phase information will be discarded. To suppress this warning, call power_to_db(np.abs(D)**2) instead.
  warnings.warn('power_to_db was called on complex input so phase '
In [43]:
log_amp2=librosa.power_to_db(C**2,top_db=40)
librosa.display.specshow(log_amp2,x_axis='time',y_axis='cqt_note')
plt.colorbar();
/anaconda3/lib/python3.6/site-packages/librosa/core/spectrum.py:865: UserWarning: power_to_db was called on complex input so phase information will be discarded. To suppress this warning, call power_to_db(np.abs(D)**2) instead.
  warnings.warn('power_to_db was called on complex input so phase '
In [44]:
chroma=librosa.feature.chroma_cqt(C=C,sr=sampling_rate)
In [45]:
librosa.display.specshow(chroma,x_axis='time',y_axis='cqt_note')
plt.colorbar();
/anaconda3/lib/python3.6/site-packages/librosa/display.py:665: UserWarning: Trying to display complex-valued input. Showing magnitude instead.
  warnings.warn('Trying to display complex-valued input. '
In [46]:
y_harmonic,y_percussive=librosa.effects.hpss(y)
In [47]:
Audio(data=y_harmonic,rate=sampling_rate)
Out[47]:
In [48]:
Audio(data=y_percussive,rate=sampling_rate)
Out[48]:
In [51]:
C_harmonic=librosa.cqt(y_harmonic,sampling_rate)
C_perc=librosa.cqt(y_percussive,sampling_rate)
plt.figure(figsize=(21,6))
plt.subplot(3,1,1),librosa.display.specshow(C**(1/3),x_axis='time',y_axis='cqt_hz');
plt.subplot(3,1,2),librosa.display.specshow(C_harmonic**(1/3),x_axis='time',y_axis='cqt_hz');
plt.subplot(3,1,3),librosa.display.specshow(C_perc**(1/3),x_axis='time',y_axis='cqt_hz');
/anaconda3/lib/python3.6/site-packages/librosa/display.py:665: UserWarning: Trying to display complex-valued input. Showing magnitude instead.
  warnings.warn('Trying to display complex-valued input. '
In [52]:
onset_envelope=librosa.onset.onset_strength(y,sampling_rate)
onsets=librosa.onset.onset_detect(onset_envelope=onset_envelope)
In [55]:
plt.figure(figsize=(21,10))
plt.subplot(2,1,1)
plt.plot(onset_envelope,label='Onset Strength')
plt.vlines(onsets,0,onset_envelope.max(),color='r',alpha=0.5,label='Onsets')
plt.xticks([]),plt.yticks([])
plt.legend(frameon=True)
plt.axis('tight')
plt.subplot(2,1,2)
librosa.display.waveplot(y,sampling_rate);
In [56]:
tempo,beats=librosa.beat.beat_track(onset_envelope=onset_envelope)
In [229]:
plt.figure(figsize=(21,6))
plt.plot(onset_envelope,label='Onset Strength')
plt.vlines(beats,0,onset_envelope.max(),color='r',alpha=0.5,label='Beats')
plt.xticks([]),plt.yticks([])
plt.legend(frameon=True)
plt.axis('tight');
In [58]:
beat_times=librosa.frames_to_time(beats)
In [59]:
y_click=mir_eval.sonify.clicks(beat_times,sampling_rate,length=len(y))
In [60]:
Audio(data=y+y_click,rate=sampling_rate)
Out[60]:
In [66]:
!pip install music21
Collecting music21
  Downloading https://files.pythonhosted.org/packages/81/de/5af13438e28b80b41e1db0d6f082204fadccd3b1d90c1951568d92df7c68/music21-5.5.0.tar.gz (18.5MB)
    100% |████████████████████████████████| 18.5MB 44kB/s eta 0:00:01
Building wheels for collected packages: music21
  Running setup.py bdist_wheel for music21 ... done
  Stored in directory: /Users/adityagudal/Library/Caches/pip/wheels/7b/21/95/d396f231b8095f30aba2a1fbffbc2411fb22eb4e611ddbed57
Successfully built music21
Installing collected packages: music21
Successfully installed music21-5.5.0
You are using pip version 9.0.1, however version 19.0.2 is available.
You should consider upgrading via the 'pip install --upgrade pip' command.
In [67]:
!pip install midiutil
Collecting MIDIUtil
  Downloading https://files.pythonhosted.org/packages/f5/44/fde6772d8bfaea64fcf5eb948124d0a5fdf5f848b14ac22a23ced53e562d/MIDIUtil-1.2.1.tar.gz (1.0MB)
    100% |████████████████████████████████| 1.0MB 987kB/s ta 0:00:011
Building wheels for collected packages: MIDIUtil
  Running setup.py bdist_wheel for MIDIUtil ... done
  Stored in directory: /Users/adityagudal/Library/Caches/pip/wheels/70/f1/24/97bde012f64820632e1e5e2935df19dfbcf9e058b0734b57cd
Successfully built MIDIUtil
Installing collected packages: MIDIUtil
Successfully installed MIDIUtil-1.2.1
You are using pip version 9.0.1, however version 19.0.2 is available.
You should consider upgrading via the 'pip install --upgrade pip' command.
In [2]:
import IPython.display as ipd
from ipywidgets import interactive_output
from ipywidgets import IntSlider,FloatSlider,fixed,Checkbox
from ipywidgets import VBox,Label
In [3]:
from midiutil import MIDIFile
from music21.tempo import MetronomeMark
from music21.note import Note,Rest
from music21.stream import Stream
from music21 import metadata
from music21 import instrument
from music21 import midi
from music21.key import Key
In [10]:
path='./Downloads/'
plt.rc('figure',figsize=(17,8))
fs=44100
nfft=2048
overlap=0.5
hop_length=int(nfft*(1-overlap))
n_bins=72
mag_exp=4
pre_post_max=6
cqt_threshold=-61
In [91]:
#filename='%sGuns N39 Roses - Sweet Child O39 Mine.mp3'%path
filename='%sLamb Of God - Walk With Me In Hell LYRICS.mp3'%path
x,fs=librosa.load(filename,sr=None,mono=True,duration=30)
print(x.shape)
print(fs)
print('Audio length:%d'%(x.shape[0]/fs))
ipd.Audio(x,rate=fs)
(1323000,)
44100
Audio length:30
Out[91]:
In [92]:
cqt_freqs=librosa.core.cqt_frequencies(n_bins=128,fmin=librosa.note_to_hz('c0'),bins_per_octave=12)
fft_freqs=librosa.fft_frequencies(sr=44100,n_fft=128)

notes_freqs=440*2**(np.arange(-57,(128-57))/12)
In [93]:
plt.figure()
plt.plot(cqt_freqs,'bo',label='CQT')
plt.plot(fft_freqs,'rD',label='FFT')
plt.plot(notes_freqs,'g',label='Notes')
plt.title('CQT vs FFT')
plt.xlabel('Bin Number')
plt.ylabel('Freq [Hz]')
plt.legend();
In [74]:
def calc_cqt(x,fs=fs,hop_length=hop_length,n_bins=n_bins,mag_exp=mag_exp):
    C=librosa.cqt(x,sr=fs,hop_length=hop_length,fmin=None,n_bins=n_bins)
    C_mag=librosa.magphase(C)[0]**mag_exp
    CdB=librosa.core.amplitude_to_db(C_mag,ref=np.max)
    return CdB
In [75]:
def cqt_thresholded(cqt,thres=cqt_threshold):
    new_cqt=np.copy(cqt)
    new_cqt[new_cqt<thres]=-120
    return new_cqt
In [76]:
def calc_onset_env(cqt):
    return librosa.onset.onset_strength(S=cqt,sr=fs,aggregate=np.mean,hop_length=hop_length)
In [77]:
def calc_onset(cqt,pre_post_max=pre_post_max,backtrack=True):
    onset_env=calc_onset_env(cqt)
    onset_frames=librosa.onset.onset_detect(onset_envelope=onset_env,
                                           sr=fs,units='frames',
                                           hop_length=hop_length,
                                           backtrack=backtrack,
                                           pre_max=pre_post_max,
                                           post_max=pre_post_max)
    onset_boundaries=np.concatenate([[0],onset_frames,[cqt.shape[1]]])
    onset_times=librosa.frames_to_time(onset_boundaries,sr=fs,hop_length=hop_length)
    return [onset_times, onset_boundaries,onset_env]
In [78]:
style = {'description_width': 'initial'}
mag_exp_slider=IntSlider(value=mag_exp, min=1, max=32, step=1,
                         description='mag_exp:',continuous_update=False)

thres_slider=IntSlider(value=-61, min=-120, max=0, step=1,description='Threshold:',continuous_update=False)

pre_post_slider=IntSlider(value=pre_post_max, min=1, max=32, step=1, 
                         description='Pre_post_max:',continuous_update=False, style=style)

backtrack_box=Checkbox(value=False,description='backtrack',disabled=False)


def inter_cqt_tuning(mag_exp,thres,pre_post_max, backtrack):
    thres=thres_slider.value
    mag_exp=mag_exp_slider.value
    pre_post_max=pre_post_slider.value
    backtrack=backtrack_box.value
    global CdB
    CdB = calc_cqt(x,fs,hop_length, n_bins, mag_exp)
    plt.figure()
    new_cqt=cqt_thresholded(CdB,thres)
    librosa.display.specshow(new_cqt, sr=fs, hop_length=hop_length, x_axis='time', y_axis='cqt_note', cmap='coolwarm')
    plt.ylim([librosa.note_to_hz('B2'),librosa.note_to_hz('B6')])
    global onsets
    onsets=calc_onset(new_cqt,pre_post_max, backtrack)
    plt.vlines(onsets[0], 0, fs/2, color='k', alpha=0.8)
    plt.title("CQT - Sweet Child O' Mine Intro")
    plt.colorbar()
    plt.show()
In [79]:
out = interactive_output(inter_cqt_tuning,  {'mag_exp': mag_exp_slider, 'thres': thres_slider, 
                                             'pre_post_max': pre_post_slider, 'backtrack':backtrack_box})
ui = VBox([mag_exp_slider, thres_slider, pre_post_slider, backtrack_box])
display(ui, out)
In [94]:
tempo, beats=librosa.beat.beat_track(y=None, sr=fs, onset_envelope=onsets[2], hop_length=hop_length,start_bpm=120.0, tightness=100, trim=True, bpm=None,units='frames')
tempo=int(2*round(tempo/2))
mm = MetronomeMark(referent='quarter', number=tempo)
In [81]:
def time_to_beat(duration, tempo):
    return (tempo*duration/60)
In [82]:
def remap(x, in_min, in_max, out_min, out_max):
    return (x - in_min) * (out_max - out_min) / (in_max - in_min) + out_min
In [83]:
def generate_sine_midi_note(f0_info, sr, n_duration, round_to_sixtenth=True):
    f0=f0_info[0]
    A=remap(f0_info[1], CdB.min(), CdB.max(), 0, 1)
    duration = librosa.frames_to_time(n_duration, sr=fs, hop_length=hop_length)
    note_duration = 0.02*np.around(duration/2/0.02) 
    midi_duration = time_to_beat(duration, tempo)
    midi_velocity=int(round(remap(f0_info[1], CdB.min(), CdB.max(), 0, 127)))
    if round_to_sixtenth:
        midi_duration=round(midi_duration*16)/16
    if f0==None:
        midi_note=None
        note_info=Rest(type=mm.secondsToDuration(note_duration).type)
        f0=0
    else:
        midi_note=round(librosa.hz_to_midi(f0))
        note = Note(librosa.midi_to_note(midi_note), type=mm.secondsToDuration(note_duration).type)
        note.volume.velocity = midi_velocity
        note_info = [note]
    midi_info = [midi_note, midi_duration, midi_velocity]
            
    n = np.arange(librosa.frames_to_samples(n_duration, hop_length=hop_length ))
    sine_wave = A*np.sin(2*np.pi*f0*n/float(sr))
    return [sine_wave, midi_info, note_info]
In [84]:
def estimate_pitch(segment, threshold):
    freqs = librosa.cqt_frequencies(n_bins=n_bins, fmin=librosa.note_to_hz('C1'),
                            bins_per_octave=12)
    if segment.max()<threshold:
        return [None, np.mean((np.amax(segment,axis=0)))]
    else:
        f0 = int(np.mean((np.argmax(segment,axis=0))))
    return [freqs[f0], np.mean((np.amax(segment,axis=0)))]
In [95]:
def estimate_pitch_and_notes(x, onset_boundaries, i, sr):
    n0 = onset_boundaries[i]
    n1 = onset_boundaries[i+1]
    f0_info = estimate_pitch(np.mean(x[:,n0:n1],axis=1),threshold=cqt_threshold)
    return generate_sine_midi_note(f0_info, sr, n1-n0)
onsets[1]
Out[95]:
array([   0,  458,  700,  733,  743,  753,  764,  783,  804,  814,  822,
        834,  845,  855,  863,  876,  888,  895,  937,  947,  957,  977,
        998, 1008, 1026, 1057, 1099, 1110, 1181, 1190, 1202, 1212, 1222,
       1232, 1242, 1253, 1262, 1274, 1283, 1292])
In [96]:
music_info = np.array([
    estimate_pitch_and_notes(CdB, onsets[1], i, sr=fs)
    for i in range(len(onsets[1])-1)
])
In [97]:
onsets
Out[97]:
[array([ 0.        , 10.63473923, 16.25396825, 17.02022676, 17.2524263 ,
        17.48462585, 17.74004535, 18.18122449, 18.66884354, 18.90104308,
        19.08680272, 19.36544218, 19.62086168, 19.85306122, 20.03882086,
        20.34068027, 20.61931973, 20.78185941, 21.75709751, 21.98929705,
        22.2214966 , 22.68589569, 23.17351474, 23.40571429, 23.82367347,
        24.54349206, 25.51873016, 25.77414966, 27.42276644, 27.63174603,
        27.91038549, 28.14258503, 28.37478458, 28.60698413, 28.83918367,
        29.09460317, 29.30358277, 29.58222222, 29.79120181, 30.00018141]),
 array([   0,  458,  700,  733,  743,  753,  764,  783,  804,  814,  822,
         834,  845,  855,  863,  876,  888,  895,  937,  947,  957,  977,
         998, 1008, 1026, 1057, 1099, 1110, 1181, 1190, 1202, 1212, 1222,
        1232, 1242, 1253, 1262, 1274, 1283, 1292]),
 array([0.        , 0.        , 0.        , ..., 0.05961746, 0.16525326,
        0.06863002])]
In [98]:
synth_audio=np.concatenate(music_info[:,0])
ipd.Audio(synth_audio, rate=fs)
note_info = list(music_info[:,2])

s = Stream()
s.append(mm)
electricguitar = instrument.fromString('electric guitar')
electricguitar.midiChannel=0
electricguitar.midiProgram=30
s.append(electricguitar)
s.insert(0, metadata.Metadata())
s.metadata.title = "Sweet Child O' Mine - Introduction"
s.metadata.composer = "Guns n' Roses"
for note in note_info:
    s.append(note)
In [99]:
key=s.analyze('key')
print(key.name)
s.insert(0, key)
B major
In [100]:
s.show('text')
s.show('midi') 
{0.0} <music21.metadata.Metadata object at 0x1c21db7a58>
{0.0} <music21.instrument.ElectricGuitar Electric Guitar>
{0.0} <music21.tempo.MetronomeMark allegro moderato Quarter=130>
{0.0} <music21.key.Key of B major>
{0.0} <music21.note.Rest rest>
{16.0} <music21.note.Rest rest>
{24.0} <music21.note.Note C#>
{25.0} <music21.note.Note F>
{25.5} <music21.note.Note F>
{26.0} <music21.note.Note F>
{26.5} <music21.note.Note F#>
{27.0} <music21.note.Note G#>
{28.0} <music21.note.Note A#>
{28.5} <music21.note.Note G#>
{28.75} <music21.note.Note F#>
{29.25} <music21.note.Note F>
{29.75} <music21.note.Note C#>
{30.25} <music21.note.Note G#>
{30.5} <music21.note.Note B>
{31.0} <music21.note.Note B>
{31.5} <music21.note.Note F#>
{31.75} <music21.note.Note F#>
{33.75} <music21.note.Note G#>
{34.25} <music21.note.Note E>
{34.75} <music21.note.Note D#>
{35.75} <music21.note.Note E>
{36.75} <music21.note.Note D#>
{37.25} <music21.note.Note F>
{37.75} <music21.note.Note F#>
{38.75} <music21.note.Note F#>
{40.75} <music21.note.Note C#>
{41.25} <music21.note.Note F#>
{43.25} <music21.note.Note C#>
{43.5} <music21.note.Note F#>
{44.0} <music21.note.Note F>
{44.5} <music21.note.Note F>
{45.0} <music21.note.Note F#>
{45.5} <music21.note.Note F#>
{46.0} <music21.note.Note F>
{46.5} <music21.note.Note C#>
{46.75} <music21.note.Note C#>
{47.25} <music21.note.Note C#>
{47.5} <music21.note.Note C#>
In [192]:
!pip install fretboard
Requirement already satisfied: fretboard in /anaconda3/lib/python3.6/site-packages
Requirement already satisfied: attrdict==2.0.0 in /anaconda3/lib/python3.6/site-packages (from fretboard)
Requirement already satisfied: PyYAML==3.12 in /anaconda3/lib/python3.6/site-packages (from fretboard)
Requirement already satisfied: svgwrite==1.1.9 in /anaconda3/lib/python3.6/site-packages (from fretboard)
Requirement already satisfied: six in /anaconda3/lib/python3.6/site-packages (from attrdict==2.0.0->fretboard)
Requirement already satisfied: pyparsing>=2.0.1 in /anaconda3/lib/python3.6/site-packages (from svgwrite==1.1.9->fretboard)
You are using pip version 9.0.1, however version 19.0.2 is available.
You should consider upgrading via the 'pip install --upgrade pip' command.
In [148]:
print(s)
<music21.stream.Stream 0x1c2cfae9b0>
In [172]:
print(s.notes.stream)
<bound method StreamIterator.stream of <music21.stream.iterator.StreamIterator for Stream:0x1c2cfae9b0 @:8>>
In [90]:
for note in s.notes:
    print(note.octave)
    print(note.name)
4
C#
5
C#
4
G#
4
F#
5
F#
4
G#
5
F
4
G#
4
C#
4
G#
4
F#
5
F#
4
G#
4
G#
4
G#
4
D#
5
C#
4
G#
4
F#
5
F#
4
G#
5
F
4
G#
4
D#
5
C#
4
G#
4
F#
5
F#
4
G#
5
F
4
G#
4
F#
5
C#
4
G#
4
F#
5
F#
4
G#
5
F
4
G#
4
F#
5
C#
4
G#
4
F#
5
F#
4
G#
In [179]:
!pip install console
Collecting console
  Downloading https://files.pythonhosted.org/packages/b3/f3/e9a12d5ab007ed3711d2cdf88bfdb9c2b39855dffcd52da8a05a294b4bc2/console-0.94-py2.py3-none-any.whl (44kB)
    100% |████████████████████████████████| 51kB 765kB/s ta 0:00:011
Collecting ezenv (from console)
  Downloading https://files.pythonhosted.org/packages/d1/3c/323d00957ec94ee3a20d445a9bec463574838a6f64a4b1182cd0e76bf8ed/ezenv-0.86-py2.py3-none-any.whl
Installing collected packages: ezenv, console
Successfully installed console-0.94 ezenv-0.86
You are using pip version 9.0.1, however version 19.0.2 is available.
You should consider upgrading via the 'pip install --upgrade pip' command.
In [202]:
from fretboard import *
In [224]:
fretboard.Fretboard(6)
Out[224]:
<fretboard.fretboard.Fretboard at 0x1c3a239470>
In [225]:
!pip install Solala
Collecting Solala
  Could not find a version that satisfies the requirement Solala (from versions: )
No matching distribution found for Solala
You are using pip version 9.0.1, however version 19.0.2 is available.
You should consider upgrading via the 'pip install --upgrade pip' command.